﻿using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.ServiceModel.Web;
using WCFServiceWebRole1.Services;

namespace WCFServiceWebRole1_Tests
{
    [TestClass]
    public class UnitTest3
    {

       // Any binding can be used. For testing, just use basic binding

        private WCFHost<user, Iusers, WebHttpBinding> wcfHost;

       // Use basic binding for local testing.

        WebHttpBinding basicHttpBinding;

        private Uri baseAddress = new Uri("http://localhost:80/Services");

        private string serviceName = "users.svc";

        [ClassInitialize()]

        public void SetUpTest()
        {

            #region Setup/Host the host and add endpoint to service

            wcfHost = new WCFHost<user, Iusers, WebHttpBinding>

("http://localhost:80/Services", "users.svc");

            wcfHost.ServiceHost.Open();

            #endregion

        }

        [TestMethod]

        public void GetVendorByById()
        {

            using (var factory = new ChannelFactory<Iusers>(wcfHost.Binding, wcfHost.EndpointAddress))
            {

                Iusers vendorClient = factory.CreateChannel();

                string vendorDetail = vendorClient.getUserByUserId("1092").response.Username;

                Assert.AreEqual(vendorDetail, "ayyappan");

            }

        }

        [ClassCleanup()]

        public void CleanUp()
        {

            if (wcfHost.ServiceHost != null)
            {

                if (wcfHost.ServiceHost.State != CommunicationState.Closed)
                {

                    wcfHost.ServiceHost.Close();

                }

            }

        }
        //[TestMethod]
        //public void MyTestMethod()
        //{
        //    var factory = new WebChannelFactory<Iusers>(new WebHttpBinding(), new Uri("http://localhost:8181/Services/users.svc"));
        //    factory.Endpoint.Behaviors.Add(new WebHttpBehavior());
        //    Iusers client = factory.CreateChannel();

        //    using (new OperationContextScope((IContextChannel)client))
        //    {
        //        if (WebOperationContext.Current != null)
        //            WebOperationContext.Current.OutgoingRequest.ContentType = "application/json";
        //        Console.WriteLine(client.getUserByUserId("1092"));
        //    }
        //}
    }
    public class WCFHost<TService, TServiceContract, TBinding> where TBinding : Binding, new()
    {

        private ServiceHost _serviceHost;
        private TBinding _binding;
        private EndpointAddress _endpointAddress;
        private Uri _baseAddress;
        private string _serviceName;

        public TBinding Binding { get { return _binding; } }

        public EndpointAddress EndpointAddress { get { return _endpointAddress; } }

        public Uri BaseAddress { get { return _baseAddress; } }

        public string ServiceName { get { return _serviceName; } }

        public ServiceHost ServiceHost { get { return _serviceHost; } }

        #region constructor

        //WCF requires a parameterless constructor to dynamically instantiate a service contract implementation

        public WCFHost(string hostBaseAddress, string serviceName)
        {

            _baseAddress = new Uri(hostBaseAddress);

            _serviceName = serviceName;

            _endpointAddress = new EndpointAddress(RemoveEndingSlash(hostBaseAddress) + "/" + serviceName);

            _serviceHost = new ServiceHost(typeof(TService), BaseAddress);

            Initialize();

        }

        //Singleton Instance overload

        public WCFHost(TService singletonInstance, string hostBaseAddress, string serviceName)
        {

            _baseAddress = new Uri(hostBaseAddress);

            _serviceName = serviceName;

            _endpointAddress = new EndpointAddress(RemoveEndingSlash(hostBaseAddress) + "/" + serviceName);

            _serviceHost = new ServiceHost(singletonInstance, BaseAddress);

            Initialize();

        }

        public void Initialize()
        {

            CreateServiceEndPoint();

            var smb = new ServiceMetadataBehavior();

            smb.HttpGetEnabled = true;

            _serviceHost.Description.Behaviors.Add(smb);

        }

        #endregion

        // Override if you need to implment different binding logic

        public virtual void CreateServiceEndPoint()
        {

            _binding = new TBinding();

            _serviceHost.AddServiceEndpoint(

            typeof(TServiceContract),

            _binding,

            _serviceName);

        }

        private static string RemoveEndingSlash(string path)
        {

            char[] charsToTrim = { '/' };

            string resultPath;

            resultPath = path.EndsWith("/") ? path.TrimEnd(charsToTrim) : path;

            return resultPath;

        }

    }
}
